package myJs.tools

import myJs.{FileSaver, Utils}
import myJs.Implicits._
import myJs.Utils._
import myJs.myPkg._
import myJs.myPkg.jquery._
import myJs.tool.Tool
import org.scalajs.dom._
import org.scalajs.dom.ext.Ajax
import org.scalajs.dom.raw.HTMLFormElement
import scalatags.Text.all
import scalatags.Text.all._

import scala.collection.immutable.SeqMap
import scala.concurrent.ExecutionContext.Implicits.global
import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}

/**
 * Created by yz on 16/9/2021
 */
@JSExportTopLevel("Enrich")
object Enrich {

  val formId = "form"
  val tableId = "table"

  def formJq = $(s"#${formId}")

  def keggResultJq = $("#keggResult")

  def goResultJq = $("#goResult")

  @JSExport("init")
  def init = {
    bootStrapValidator
    registerEvent
    GoResult.init
    KeggResult.init
  }

  def registerEvent = {
    $(document.body).on("click", s".mySearch", "", (y: Element) => {
      mySearch
    })
    $(document.body).on("click", s".myShowExample", "", (y: Element) => {
      showExample(y)
    })
    $(document.body).on("click", s".myShowExampleFile", "", (y: Element) => {
      showExampleFile
    })
    $(document.body).on("click", s".downloadPng", "", (y: Element) => {
      val imageJq = $(y).parents(".charts").find("img")
      val fileName = $(y).dataValue
      Tool.downloadPng(imageJq, fileName)
    })
  }

  val eg =
    s"""
       |XP_042474805.1
       |XP_042474806.1
       |XP_042474807.1
       |XP_042474808.1
       |XP_042474809.1
       |XP_042474810.1
       |XP_042474811.1
       |XP_042474812.1
       |XP_042474813.1
       |XP_042474814.1
       |""".stripMargin.trim

  def showExampleFile = {
    val content = eg
    Tool.downloadTxt("example.txt", content)
  }

  def showExample(y: Element) = {
    val inputJq = $(y).parents(".form-group").find(":input")
    val str = eg
    inputJq.`val`(str)
  }

  def mySearch = {
    val value = $(":input[name='anaMethod']").`val`
    if (value == "kegg") {
      keggEnrich
    } else {
      goEnrich
    }
  }

  def inputCheck(formId: String) = {
    val text = $(s"#${formId} #geneId").`val`.toString
    val file = $(s"#${formId} #input-1").`val`.toString
    if (file.nonEmpty && text.nonEmpty) {
      Swal.swal(SwalOptions.title("Error").text("Please either enter gene id into the box or upload a file, not both!").
        `type`("error"))
      false
    } else if (file.isEmpty && text.isEmpty) {
      Swal.swal(SwalOptions.title("Error").text("Please enter gene ID or upload file!").
        `type`("error"))
      false
    } else true
  }

  def keggEnrich = {
    val bv = formJq.bv
    val resultJq = keggResultJq
    bv.validate()
    val valid = bv.isValid()
    if (valid && inputCheck(formId)) {
      val formData = new FormData(document.getElementById(formId).asInstanceOf[HTMLFormElement])
      val element = div(id := "content",
        span(id := "info", "Query...",
          span(id := "progress")), " ",
        img(src := "/assets/images/running2.gif", cls := "runningImage", width := 30, height := 20)
      ).render
      val layerOptions = LayerOptions(icon=16,shade=0.01,time=20000000)
      val index = layer.msg(element, layerOptions)
      val url = g.jsRoutes.controllers.ToolsController.keggEnrich().url.toString
      val xhr = new XMLHttpRequest
      xhr.open("post", url)
      xhr.upload.onprogress = Utils.progressHandlingFunction
      xhr.onreadystatechange = (e) => {
        if (xhr.readyState == XMLHttpRequest.DONE) {
          layer.close(index)
          val rs = xhr.responseText.toJDJAn
          val valid = rs("valid").toB
          if (valid) {
            KeggResult.refreshData(rs)
            goResultJq.hide()
            resultJq.show()
          } else {
            g.swal("Error", rs.myGet("message"), "error")
            resultJq.hide()
          }
        }
      }
      xhr.send(formData)
    }
  }


  def goEnrich = {
    val bv = formJq.bv
    val resultJq = goResultJq
    bv.validate()
    val valid = bv.isValid()
    if (valid && inputCheck(formId)) {
      val formData = new FormData(document.getElementById(formId).asInstanceOf[HTMLFormElement])
      val element = div(id := "content",
        span(id := "info", "Query...",
          span(id := "progress")), " ",
        img(src := "/assets/images/running2.gif", cls := "runningImage", width := 30, height := 20)
      ).render
      val layerOptions = LayerOptions(icon=16,shade=0.01,time=20000000)
      val index = layer.msg(element, layerOptions)
      val url = g.jsRoutes.controllers.ToolsController.goEnrich().url.toString
      val xhr = new XMLHttpRequest
      xhr.open("post", url)
      xhr.upload.onprogress = Utils.progressHandlingFunction
      xhr.onreadystatechange = (e) => {
        if (xhr.readyState == XMLHttpRequest.DONE) {
          layer.close(index)
          val rs = xhr.responseText.toJDJAn
          val valid = rs("valid").toB
          if (valid) {
            GoResult.refreshData(rs)
            keggResultJq.hide()
            resultJq.show()
          } else {
            g.swal("Error", rs.myGet("message"), "error")
            resultJq.hide()
          }
        }
      }
      xhr.send(formData)
    }
  }

  def bootStrapValidator = {
    val maxNumber = Double.MaxValue
    val dict: js.Dictionary[js.Any] = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> js.Dictionary(
        "cutoff" -> {
          val info = "Cutoff number"
          js.Dictionary(
            "validators" -> js.Dictionary(
              "notEmpty" -> js.Dictionary(
                "message" -> s"${info} is required！"
              ),
              "integer" -> js.Dictionary(
                "message" -> s"${info} must be integer！",
              ),
              "between" -> js.Dictionary(
                "min" -> 1,
                "max" -> maxNumber,
                "message" -> s"${info} must be more than 0!",
              ),
            )
          )
        },
        "pValue" -> {
          val info = "P-Value cutoff number"
          js.Dictionary(
            "validators" -> js.Dictionary(
              "notEmpty" -> js.Dictionary(
                "message" -> s"${info} is required！"
              ),
              "numeric" -> js.Dictionary(
                "message" -> s"${info} must be numeric！",
              ),
              "between" -> js.Dictionary(
                "min" -> 0,
                "max" -> maxNumber,
                "message" -> s"${info} must be more than 0!",
              ),
            )
          )
        },
        "file" -> {
          val info = "Gene Id file"
          js.Dictionary(
            "validators" -> js.Dictionary(
              "file" -> js.Dictionary(
                "message" -> s"${info} must is a txt file！",
                "extension" -> "txt",
              ),
            )
          )
        },
      )
    )
    formJq.bootstrapValidator(dict)
  }

}
